package com.andnnl.snooker;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

/**
 * Created by chenss on 2017/9/1.
 */
public class MyPanel extends JPanel    //我自己的面板，用于绘图和实现绘图区域
{
    public static final Color RED = Color.RED;
    private static final int DEFAULT_W = 800;
    private static final int DEFAULT_H = 600;
    static final double DIAM = 100;//直径

    //覆盖JPanel的paint方法
    //Graphics是绘图的重要类，可以理解成一支画笔
    public void paint(Graphics g) {
        //1.调用父类函数完成初始化
        super.paint(g);     //这句话不能少
//        testPaint((Graphics2D) g);
        paintSnooker((Graphics2D) g);

    }

    private static void testPaint(Graphics2D g) {
        //System.out.println("被调用");        //证明别调用
        Graphics2D g2d = g;

        g2d.setStroke(new BasicStroke(2f));//粗线
        //画圆
        g2d.drawOval(70, 70, 100, 100);
        //画直线
        g2d.drawLine(20, 30, 20, 80);
        //画出矩形边框
        g2d.drawRect(50, 50, 100, 50);
        //画填充矩形
        g2d.setColor(Color.BLUE);     //设置颜色
        g2d.fillRect(80, 60, 40, 60);

        g2d.setColor(Color.BLACK);     //设置颜色
//        g2d.draw3DRect(200,200,150,150,true);
//        g2d.draw3DRect(210,210,150,150,false);

        double centerX = DEFAULT_W / 2;
        double centerY = DEFAULT_H / 2;

        double conerX = centerX + 100;
        double conerY = centerY + 100;

        Rectangle2D rect = new Rectangle2D.Double();
        rect.setFrameFromCenter(centerX, centerY, conerX, conerY);

        Ellipse2D ellipse = new Ellipse2D.Double();
        ellipse.setFrame(centerX - DIAM / 2, centerY - DIAM / 2, DIAM, DIAM);
        g2d.draw(ellipse);


        Line2D line = new Line2D.Double(ellipse.getCenterX(), ellipse.getCenterY(), ellipse.getCenterX() + DIAM, ellipse.getCenterY());

        Ellipse2D ellipse2 = new Ellipse2D.Double();
        ellipse2.setFrame(ellipse.getX() + DIAM, ellipse.getY(), DIAM, DIAM);

        g2d.draw(ellipse2);

        g2d.draw(line);

        Line2D line2 = new Line2D.Double(ellipse2.getCenterX(), ellipse2.getCenterY() - 200, ellipse2.getCenterX(), ellipse2.getCenterY() + 200);
        g2d.draw(line2);

//        Ellipse2D circle=new Ellipse2D.Double();
//        double radius= Point2D.distance(centerX, centerY, conerX, conerY);
//        circle.setFrameFromCenter(centerX,centerY,centerX+radius,centerY+radius);
//        g2d.draw(circle);


//        for (int i=1;i<=5;i++) {
//
//
//            double offset=10*(i);
//            Ellipse2D ellipse3 = new Ellipse2D.Double();
//
//            double y = getCircleY(DIAM, ellipse.getCenterX(), ellipse.getCenterY(), ellipse.getCenterX() + offset);
//            System.out.println("ell3: i:"+i+" X:"+(ellipse.getCenterX() + offset)+" Y:"+y);
//            ellipse3.setFrame(ellipse.getCenterX() + offset - DIAM / 2, y - DIAM / 2, DIAM, DIAM);
//            g2d.draw(ellipse3);
//
//            Line2D line3 = new Line2D.Double(ellipse.getCenterX(), ellipse.getCenterY(), ellipse3.getCenterX(), ellipse3.getCenterY());
//            g2d.draw(line3);
//
//            Line2D line4 = new Line2D.Double(ellipse3.getCenterX(), 0, ellipse3.getCenterX(), 1000);
//            g2d.draw(line4);
//        }
    }

    public static double distance(Point p1, Point p2) {
        return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
    }

    public static double getCircleY(double distance, double p1X, double p1Y, double p2X) {
//        distance=Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
        //求p2Y=distance
//        Math.pow(distance, 2)-Math.pow(p1.x - p2.x, 2)=Math.pow(p1X - p2X, 2)

        return Math.sqrt(Math.pow(distance, 2) - Math.pow(p1X - p2X, 2)) + p1Y;
    }

    public void paintSnooker(Graphics g) {
        double centerX = DEFAULT_W / 2;
        double centerY = DEFAULT_H / 2;

        //1.调用父类函数完成初始化
        super.paint(g);     //这句话不能少
        //System.out.println("被调用");        //证明别调用
        Graphics2D g2d = (Graphics2D) g;
        final BasicStroke bigStroke = new BasicStroke(2f);
        final Stroke smallStroke = new BasicStroke(1f);//细线
//        g2d.setStroke(smallStroke);//细线
        g2d.setStroke(bigStroke);//粗线
        g2d.setFont(new Font("微软雅黑", Font.PLAIN, 20));//字体
        double last = 0;
        int[] jds = {5, 10, 15, 20, 25, 30,    35, 40, 45, 50, 60}; //要划的角度列表
//        String[] jdStr={"1/6","1/3","1/2","2/3","5/6","1","1+1/7","1.3","1.4","1.55","1+3/4","1.9","1.99"};
        String[] jdStr = {"1/6", "1/3", "1/2", "2/3", "5/6", "1", "1+1/7", "1+1/3", "1+2/5", "1+1/2", "1+3/4", "1.9", "1.99"};//瞄准的点位，按比例
        int[] jdGs = {6, 3, 2, 3, 6, 2,      6 + 7, 6 + 3, 6 + 5, 6 + 2, 6 + 4, 6 + 10, 6 + 10};//刻度线，球内（前6个）和球外的刻度
        int[] jdGs2 = {6, 6, 4, 3, 5, 2,     5, 3, 3, 4, 6, 6, 6};//2球碰撞点，刻度线，全在球内
        String[] jdStr2 = {"1/12", "1/6", "1/4", "1/3", "2/5", "1/2", "3/5", "1+2/3(左一丝)", "1+2/3(右一丝)","1+3/4", "1+1/2", "1+5/6", "1.9"};//瞄准的点位，按比例
//        int[] jdsPrint={0,0,0,0,0,0,0,0,0,0,0,0,0};
        int[] jdsPrint = new int[jds.length];
        Color c = g2d.getColor();
        g2d.drawString("碰撞点", (float)+ 10, 180);//碰撞点瞄准位
        g2d.drawString("击球点", (float)+ 10, 220);//击球点瞄准位

//        Stroke stroke = g2d.getStroke();
        for (int i = 1; i <= 90; i++) {
//            double offset=10*(i);
            double offset = i * DIAM / 90;

            Ellipse2D ellipse = new Ellipse2D.Double();
            ellipse.setFrame(last + DIAM / 2, centerY - DIAM / 2, DIAM, DIAM);

            Ellipse2D ellipse2 = new Ellipse2D.Double();

            double y = getCircleY(DIAM, ellipse.getCenterX(), ellipse.getCenterY(), ellipse.getCenterX() + offset);
            ellipse2.setFrame(ellipse.getCenterX() + offset - DIAM / 2, y - DIAM / 2, DIAM, DIAM);

            //角度线（2个球中心点连线）
            Line2D line3 = new Line2D.Double(ellipse.getCenterX(), ellipse.getCenterY(), ellipse2.getCenterX(), ellipse2.getCenterY());

//            g2d.draw(line4);



            double x1 = line3.getX1();
            double y1 = line3.getY1();
            double x2 = line3.getX2();
            double y2 = line3.getY2();
//
//            double x3=line4.getX1();
//            double y3=line4.getY1();
//            double x4=line4.getX2();
//            double y4=line4.getY2();


            //是弧度。例如ACOS(0.5)/PI()*180=60°

//            直线的斜率公式：k=(y2-y1)/(x2-x1)
            double k = (y2 - y1) / (x2 - x1);
            //斜率求角度
            int jd = 90 - (int) Math.ceil(Math.atan(k) * 180 / Math.PI);
            for (int j = 0; j < jds.length; j++) {
                if (jds[j] == jd && jdsPrint[j] == 0) {
                    g2d.draw(ellipse);
                    g2d.draw(ellipse2);
                    g2d.draw(line3);

                    //击球竖线
                    Line2D line4 = new Line2D.Double(ellipse2.getCenterX(), 0, ellipse2.getCenterX(), DIAM*6);
                    g2d.setColor(Color.BLACK);
                    g2d.draw(line4);
                    g2d.setColor(c);//恢复旧颜色

                    //2个球的接触点，划条直线(蓝色线)
                    Line2D line7 = new Line2D.Double((ellipse.getCenterX() + ellipse2.getCenterX()) / 2, 0, (ellipse.getCenterX() + ellipse2.getCenterX()) / 2, DIAM*6);
                    g2d.setColor(Color.BLUE);
                    g2d.draw(line7);
                    g2d.setColor(c);//恢复旧颜色

                    //向左上延申的直线
                    //k=(y2-y1)/(x2-x1)   x2已经知 y2=k(x2-x1)+y1
                    double yy2 = k * (last - ellipse.getCenterX()) + ellipse.getCenterY();
                    Line2D line6 = new Line2D.Double(ellipse.getCenterX(), ellipse.getCenterY(), last, yy2);
//                    g2d.draw(line6);

                    last = last + DIAM + DIAM / 2+(j>=6?30:0);




                    System.out.println("jd:" + jd);
                    jdsPrint[j] = 1;
                    g2d.setColor(Color.BLUE);

                    g2d.drawString("" + jdStr2[j], (float) line4.getX1() + 10, 180);//碰撞点瞄准位
                    g2d.setColor(c);

                    g2d.drawString("" + jd + "度", (float) line4.getX1() + 10, 200);//打印度数
                    g2d.drawString("" + jdStr[j], (float) line4.getX1() + 10, 220);//击球点瞄准位

                    //2个球的碰撞点的刻度，画在下面
                    drawKd(g2d, ellipse.getCenterX(), ellipse.getCenterY() + 11, DIAM / 2, jdGs2[j], Color.BLUE);//球内最多6个刻度
//                    刻度线
                    if (jdGs[j] <= 6) {
                        //球内刻度
                        Line2D line5 = new Line2D.Double(ellipse.getCenterX(), ellipse.getCenterY(), ellipse.getCenterX() + DIAM / 2, ellipse.getCenterY());
                        g2d.draw(line5);
                        drawKd(g2d, ellipse.getCenterX(), ellipse.getCenterY(), DIAM / 2, jdGs[j], Color.RED);
                    } else {
                        //球外刻度
                        Line2D line5 = new Line2D.Double(ellipse.getCenterX() + DIAM / 2, ellipse.getCenterY(), ellipse.getCenterX() + DIAM, ellipse.getCenterY());
                        g2d.draw(line5);
                        drawKd(g2d, ellipse.getCenterX() + DIAM / 2, ellipse.getCenterY(), DIAM / 2, jdGs[j] - 6, Color.RED);//球内最多6个刻度
                    }


                    double jcX_len = (ellipse.getCenterX() + ellipse2.getCenterX()) / 2 - ellipse.getCenterX();//接触点离目标球的x坐标距离
                    double jcY_len_percent = jcX_len / (DIAM / 2);//与半径占比
                    System.out.println("与半径占比 jcX_len:" + jcX_len + " jcY_len_percent:" + jcY_len_percent);
                    break;
                }
            }


            //打印说明
            int lineY =(int) (DIAM*6)+ 30;
            int lineX = 10;
            int lineHeight = 20;
            g2d.drawString("蓝色竖线为球的碰撞点，可以通过瞄准尾部来确定(8球的话，记住瞄准到的花纹的位置，回到击球位看是属于哪个球型)", (float)  lineX, lineY+=lineHeight);//
            g2d.drawString("黑色竖线为球的击球点", (float)  lineX, lineY+=lineHeight);//
        }
    }

    private void drawKd(Graphics2D g2d, double x, double y, double width, int num) {
        drawKd(g2d, x, y, width, num, Color.RED);
    }

    private void drawKd(Graphics2D g2d, double x, double y, double width, int num, Color color) {
        Color c = g2d.getColor();
        g2d.setColor(color);
        double inerval = width / num;
        for (int i = 0; i <= num; i++) {
            Line2D line = new Line2D.Double(x + inerval * i, y - 10, x + inerval * i, y);
            g2d.draw(line);
        }
        g2d.setColor(c);
    }
}